- /* sint.h by K.Tsuru */
- // file id = 40 BRADIX
- /*********************************************************
- SInteger class in binary radix(BRADIX)
- Using the calculation factorial n!, etc.
- For speed the result is written on a reference argument.
- e.g. IIAdd(a, b, r); ---- r=a+b;
- But exept in a large roop, usual statements such as "r=a+b;"
- are allowed to use.
- ***********************************************************/
- #ifndef S_DEC_INT_H
- #define S_DEC_INT_H
-
- //a paramerter for the divide radix conversion SInteger to SLong
- // figures =< iNconvDecMaxFig : NConvToDec() is faster than DConvertTodec()
- const uint iNconvDecMaxFig = 225u;
- //a paramerter for the divide radix conversion SInteger to SLong
- // figures =< iNconvBinMaxFig : BSConvToBin() is faster than ConvToBin()
- // ver. 2.17
- const uint iNconvBinMaxFig = 10000u;
- SInteger BSConvToBin(const SLong& x); // ver. 2.17 3557
- SInteger SCConvToBin(const SLong& x); // ver. 2.18 3558
-
- class SInteger : public SLong {
- //SLong only, cannot use in this class and has no body.
- SInteger(const char *s);
- SInteger& operator=(const char *s);
- SInteger& MultPow10(long p);
- long DFigures() const;
- //set a double value
- void SetIDouble(double d); // 401
- public:
- //radix conversion DRADIX --> BRADIX
- SInteger NConvToBin(const SLong& m); // normal method 402. Change friend to member since version 2.20
- SInteger ConvToBin(const SLong& m); // ver. 2.17 402
- //For operator*() see below
- friend SInteger operator/(const SInteger& m, const SInteger& n);// 404
- friend SInteger operator/(const SInteger& m, double n); // 405
- SInteger& operator/=(const SInteger& n) { return (*this = *this / n); }
- SInteger& operator/=(double d) { return (*this = *this / d); }
-
- friend SInteger operator%(const SInteger& m, const SInteger& n); // 406
- friend SInteger operator%(const SInteger& m, double d); // 407
- SInteger& operator%=(const SInteger& n) { return (*this = *this % n); }
- SInteger& operator%=(double d) { return (*this = *this % d); }
- //bit operators
- friend SInteger operator&(const SInteger& m, const SInteger& n);//408
- friend SInteger operator|(const SInteger& m, const SInteger& n);//409
- SInteger& operator&=(const SInteger& n) { return (*this = *this & n); }
- SInteger& operator|=(const SInteger& n) { return (*this = *this | n); }
- //bit shift operator, n > 0 : to left, n < 0 : to right
- SInteger& BitShift(long n); // 410
- friend SInteger operator>>(const SInteger& m, ulong n); // 411
- friend SInteger operator<<(const SInteger& m, ulong n); // 412
- SInteger& operator>>=(ulong n) { return (*this = *this >> n); }
- SInteger& operator<<=(ulong n) { return (*this = *this << n); }
- //roughly estimated figures in DRADIX
- uint FigInDRadix(){
- double f = (double)Head()*log10((double)BRADIX)/DFIGURES + 1.0;
- return (uint)f +1u;
- }
- //BRADIX --> DRADIX
- SLong NConvToDec() const; //normal method 413
- SLong DConvToDec() const; //divide method by FFT 414
- SLong HConvToDec() const; // Horner's method(for a reference)415
- //Head()+1 =< iNconvDecMaxFig : NConvToDec() is faster than DConvTodec()
- SLong ConvToDec() const; // 416
- //constructors
- SInteger():SLong(BIN_INT, 0){}
- //initialized by a double value
- SInteger(double initialValue):SLong(BIN_INT, 0){
- SetIDouble(initialValue);
- }
- //by size and initial value
- SInteger(uint v_sz, double initialValue):SLong(BIN_INT, v_sz){
- if(initialValue != 0.0) SetIDouble(initialValue);
- }
- //copy constructor
- SInteger(const SInteger& a):SLong(a){}
- //SLong constructor
- //This cannot use for radix convesion. If use,a runtime error will occure.
- //This is necessary to use the operator*() of SLong class.
- SInteger(const SLong& a):SLong(a){
- if(a.Type() != BIN_INT) SetError(RADIX_ERR, "SI(SL)", 41);
- }
- //destructor
- ~SInteger(){} // do nothing
- SInteger& operator=(double d){ SetIDouble(d); return *this; }
- /****************************************************************************
- This is also necessary to use the operator*() of SLong class and cannot use
- for radix convesion.
- If an automatic radix conversion is implemented, two "=" statements
- 1. SL = SI*SI; ----- lhs SL has a type BIN_INT(BRADIX).Needs for operator*().
- 2. SL = SI; -------- call radix conversion.
- have different meaning each other.
- ****************************************************************************/
- SInteger& operator=(const SLong& a){
- if(a.Type() != BIN_INT) SetError(RADIX_ERR, "SI = SL", 42);
- SNumber::CopyValue(a, SUBS);
- return *this;
- }
- SInteger& operator=(const SInteger& a){
- if(this != &a) SNumber::CopyValue(a, SUBS);
- return *this;
- }
- //sign operator
- SInteger operator+() const { return *this; }
- //If this does not exist, a statement "t = -q/four;" is ambiguous between
- //SL/SL and SI/SI.
- SInteger operator-() const{
- SInteger r(*this); r.ChangeSign(417); return r;
- }
- /***************************************
- friend functions
- Set calcuration result in "SInteger& r".
- [Notice on specifications]
- The signs of m and n are arbitrary(+, - or 0) different from LLAdd(m,n).
- ****************************************/
- friend void IIAdd(const SInteger& m, const SInteger& n, SInteger& r);//r=m+n 420
- friend void IsAdd(const SInteger& m, fType s, SInteger& r); //r=m+s 421
- friend void IISub(const SInteger& m, const SInteger& n, SInteger& r);//r=m-n 422
- friend void IsSub(const SInteger& m, fType s, SInteger& r); //r=m-s 423
- friend void IsMult(const SInteger& m, ulong x, SInteger& r); //r=m*s 424
- //quot and remainder SI/SI, call KnuthLLDiv(m,n,r,rem) only
- friend void IIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, int rem);// 425
- //if you do not need the remainder, set rem = 0.
- friend void KnuthIIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, int rem); //426
- /**********************************************************
- SI/SI by Newton's method in DRADIX
- 1.Radix conversion m and n to SLong.
- 2.Call NewtonLLdiv()
- Due to the overhead of radix converision it is not so fast.
- If you want to use, please directly call this function.
- ************************************************************/
- friend void NewtonIIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, bool needRem);//427
- /*SInteger/(short number)*/
- // r = m/n (0 < n <= ULONG_MAX/BRADIX), return the remainder whose definition is same
- // as SLong or div() in C/C++.
- friend long IsDiv(const SInteger& m, ulong n, SInteger& r); // 428
- //Radix conversion into SLong and output it.
- long Put(long fig=5, int perLine = 0, int mode = CRLF, int delmt=' ') const {
- SLong a = ConvToDec(); // radix conversion
- return a.Put(fig, perLine, mode, delmt);
- }
- long Puts(long fig=5, int perLine = 0, int mode = CRLF, int delmt=' ') const {
- return Put(fig, perLine, mode|END_CR, delmt);
- }
- // It outputs in the four hexadecimal figures with radix = BRADIX = 2^15.
- // The maximum vakue of figure is "7fff".
- friend ostream& operator<<(ostream& os, const SInteger& m); // 430
-
- SInteger& operator+=(const SInteger& n) { IIAdd(*this, n, *this); return *this; }
- SInteger& operator-=(const SInteger& n) { IISub(*this, n, *this); return *this; }
- //++m, --n prefix. faster than m++, n-- because do not make copy.
- SInteger& operator++() {
- IsAdd(*this, 1, *this); return *this;
- }
- SInteger& operator--() {
- IsSub(*this, 1, *this); return *this;
- }
- //m++, n-- postfix
- const SInteger operator++(int){
- SInteger oldValue(*this);
- IsAdd(*this, 1, *this);
- return oldValue;
- }
- const SInteger operator--(int){
- SInteger oldValue(*this);
- IsSub(*this, 1, *this);
- return oldValue;
- }
- //operator*()
- //m*n If these are not provided, in "a*b+c*d" a SLong's operator+() is called.
- SInteger& operator*=(const SInteger& n) { return *this = LLMult(*this, n); }
- friend SInteger operator*(const SInteger& m, double d); //m*d 445
- friend SInteger operator*(double d, const SInteger& m){ return m*d; } // d*m
- SInteger& operator*=(double d) { return (*this = *this * d); } // apply m*d
- };
- /**********************************************************************
- Plus and minus operators
- Inside the function, IIAdd() or IISub() is called.
- For large roop, please directly call faster function IIAdd or IISub.
- ************************************************************************/
- inline SInteger operator+(const SInteger& m, const SInteger& n){ // m+n
- SInteger r(m);
- r += n;
- return r;
- }
- inline SInteger operator-(const SInteger& m, const SInteger& n) { // m-n
- SInteger r(m);
- r -= n;
- return r;
- }
- inline SInteger operator*(const SInteger& m, const SInteger& n) {
- return LLMult(m, n);
- }
- #endif // S_DEC_INT_H
sint.h : last modifiled at 2017/03/17 11:10:42(8,733 bytes)
created at 2016/04/11 11:18:59
The creation time of this html file is 2017/10/11 16:07:52 (Wed Oct 11 16:07:52 2017).